#!/bin/sh
ViewAppIDMsg="AppID's are viewable at http://developer.valvesoftware.com/wiki/Steam_Application_IDs"

GetScreenWidth(){
	stty size 2>/dev/null | cut -d " " -f 2
}
Status(){
  local check=$?
  local cols=$(GetScreenWidth)
  [ "$cols" ] || cols=80
  local scol=$(($cols - 7))
  if [ $check = 0 ]; then
    echo "\033[${scol}G\033[1;32mOK\033[0;39m"
  else
    if [ $@ ]; then
      $@
    else
      echo "\033[${scol}G\033[1;31mError\033[0;39m"
    fi
  fi    
}
Separator(){
  if [ $1 ]; then local sepchar="$1"; else local sepchar=" "; fi
  local cols=$(GetScreenWidth)
  [ "$cols" ] || cols=80
  for x in $(seq 1 $cols); do
    echo -n "$sepchar"
  done && echo ""
}
EchoBold(){
  if [ "$1" = "-n" ]; then shift; echo -n "\033[1m$@\033[0m"; else echo "\033[1m$@\033[0m"; fi
}
EchoRed(){
  if [ "$1" = "-n" ]; then shift; echo -n "\033[31m$@\033[0m"; else echo "\033[31m$@\033[0m"; fi
}
EchoGreen(){
  if [ "$1" = "-n" ]; then shift; echo -n "\033[32m$@\033[0m"; else echo "\033[32m$@\033[0m"; fi
}
Title(){
  echo "\n\033[7m     $@     \033[0m"
  Separator "="
}  
Longline(){
	cols=$(GetScreenWidth); [ "$cols" ] || cols=80
	echo "$@" | fold -sw$cols
}


PrintSteamCMDOut(){
  printf "\n"
  while top -bn 1 | grep "steamcmd" >/dev/null; do
    local LOGLINE="`sudo tail -2 /tmp/ezgmodds.tmp | head -1`"
    if [ "$LOGLINE" ]; then
      EchoGreen -n "\r\033[K    $LOGLINE"
    fi
    sleep 1
  done
# Check for "Login Failure: No Connection"
  echo -n "\r\033[K"
  if cat /tmp/ezgmodds.tmp | grep "Login Failure:"; then
    EchoRed "\n  SteamCMD failed to connect to Steam.\n  Please check your connection..."
  fi
  if [ "$?" -ne "0" ]; then
    EchoRed "\n  SteamCMD exited with code $?"
  else
    StatusOK
  fi
  sudo rm -f /tmp/ezgmodds.tmp
}

PrintAptGetOut(){
  StatusOK(){
    local cols=$(GetScreenWidth)
    [ "$cols" ] || cols=80
    local scol=$(($cols - 7))
    echo "\033[1A\033[${scol}G\033[1;32mOK\033[0;39m"
  }
  printf "\n"
  while top -bn 1 | grep "apt-get" >/dev/null; do
    local LOGLINE="`sudo tail -1 /tmp/ezgmodds.tmp`"
    if [ "$LOGLINE" ]; then
      EchoGreen -n "\r\033[K    $LOGLINE"
    fi
    sleep 1
  done
  echo -n "\r\033[K"
  if [ "$?" -ne "0" ]; then
    EchoRed "\n  apt-get exited with code $?"
  else
    StatusOK
  fi
  sudo rm -f /tmp/ezgmodds.tmp
}

Install(){
  Title "Installing GarrysModDS"
  
  if [ ! -f /home/steam/steamcmd/steamcmd.sh ]; then InstallSteamcmd 1; fi

  sudo rm -f /tmp/ezgmodds.tmp
  printf "%s" "  Downloading GarrysModDS"
  sudo su -c "bash /home/steam/steamcmd/steamcmd.sh +login anonymous +app_update 4020 validate +quit 1>/tmp/ezgmodds.tmp 2>/tmp/ezgmodds.tmp" steam &
  PrintSteamCMDOut

  printf "%s" "  Checking /home/steam/.steam/sdk32"
  sudo mkdir -p /home/steam/.steam/sdk32
  Status

  printf "%s" "  Fix: Linking libsteam.so"
  sudo ln -s /home/steam/Steam/steamapps/common/GarrysModDS/bin/libsteam.so /home/steam/.steam/sdk32/libsteam.so
  Status

  if [ "`uname -m`" != "i686" ]; then
    printf "%s" "  Fix: Copying libstdc++.so.6 from steamcmd/linux32"
    sudo cp /home/steam/steamcmd/linux32/libstdc++.so.6 /home/steam/Steam/steamapps/common/GarrysModDS/bin/libstdc++.so.6
    Status
  fi

  printf "%s" "  Installing srcds_options file"
  sudo su -c "echo \"+maxplayers 36 +map gm_flatgrass \" >/home/steam/Steam/steamapps/common/GarrysModDS/srcds_options" steam
  Status

  printf "%s" "  Creating basic server.cfg  `EchoRed Please edit before starting.`"
  Configure
  Status

  printf "%s" "  Checking permissions"
  sudo chown -R steam:steam /home/steam 2>/dev/null
  Status

  printf "\n"
}

InstallSteamcmd(){
  
  if [ ! $1 ]; then Title "Installing SteamCMD from Valve"; fi

  printf "%s" "  Checking file limit"
  ulimit -n 2048
  Status
  
  sudo rm -f /tmp/ezgmodds.tmp
  printf "%s" "  Updating apt-get repositories"
  sudo apt-get update 1>/tmp/ezgmodds.tmp 2>&1 &
  PrintAptGetOut

  printf "%s" "  Adding user \"steam\""
  sudo adduser --disabled-password --gecos "" steam 1>/dev/null 2>/dev/null
  Status

  sudo mkdir -p /home/steam/steamcmd
  printf "%s" "  Checking steam home permissions"
  sudo chown -R steam:steam /home/steam
  Status

  cd /home/steam/steamcmd
  printf "%s" "  Adding cron trigger"
  ( sudo crontab -l 2>/dev/null | grep -Fv ezgmodds_cron.sh; printf -- "*/5 * * * * /usr/local/bin/ezgmodds cron\n" ) | sudo crontab
  Status
    
  if [ "`uname -m`" != "i686" ]; then
    sudo rm -f /tmp/ezgmodds.tmp
    printf "%s" "  Checking ia32-libs"
    sudo apt-get -y install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 libstdc++5:i386 libstdc++6:i386 1>/tmp/ezgmodds.tmp 2>&1 &
    PrintAptGetOut
  fi
  
  sudo rm -f /tmp/ezgmodds.tmp
  printf "%s" "  Installing screen"
  sudo apt-get -y install screen 1>/tmp/ezgmodds.tmp 2>&1 &
  PrintAptGetOut
    
  printf "%s" "  Downloading steamcmd_linux.tar.gz"
  sudo wget -cq http://media.steampowered.com/installer/steamcmd_linux.tar.gz
  Status

  printf "%s" "  Deflating"
  sudo su -c "tar -xvzf /home/steam/steamcmd/steamcmd_linux.tar.gz 1>/dev/null" steam
  Status

  sudo rm -f /home/steam/steamcmd/steamcmd_linux.tar.gz
    
  Update 1
    
  if [ "`uname -m`" != "i686" ]; then
    sudo mkdir -p /home/steam/.steam
    printf "%s" "  Linking 32-bit libraries"
#   sudo cp -f /home/steam/steamcmd/linux32/* /home/steam/.steam/sdk32/
    sudo ln -s /home/steam/.steam/sdk32 /home/steam/steamcmd/linux32
    Status
  fi
  
  if [ ! $1 ]; then printf "\n"; fi
}

Start(){
  if [ ! $1 ]; then Title "Start GarrysModDS"; fi
  if top -bn 1 | grep "srcds_linux" >/dev/null; then
    EchoRed "  GarrysModDS is already running."
  else
    echo "  Starting GarrysModDS"
    if [ ! $1 ]; then EchoBold -n "  Type \"ezgmodds console\" to enter the console"; fi
    sudo su -c "screen -A -m -d -S GarrysModDS sh /home/steam/Steam/steamapps/common/GarrysModDS/srcds_run -game garrysmod `cat /home/steam/Steam/steamapps/common/GarrysModDS/srcds_options`" steam
    Status
  fi
  if [ ! $1 ]; then printf "\n"; fi
}

Stop(){
  if top -bn 1 | grep "srcds_linux" >/dev/null; then
    if [ ! $1 ]; then Title "Stop GarrysModDS"; fi
    
    printf "%s" "  Stopping GarrysModDS"
    sudo killall -SIGINT su 1>/dev/null 2>/dev/null
    sleep 5

    if top -bn 1 | grep "srcds_linux" >/dev/null; then
      printf "%s" "...  Still running.  Forcing GarrysModDS to exit"
      sudo killall -g srcds_linux 1>/dev/null 2>/dev/null
      sleep 3
      Status
    else
      Status
    fi
    
    if top -bn 1 | grep "srcds_linux" >/dev/null; then
      EchoRed "  Failed to stop GarrysModDS"
    fi
  else
    if [ ! $1 ]; then EchoRed "  GarrysModDS is not running"; fi
  fi
    
  if [ ! $1 ]; then printf "\n"; fi
}

Restart(){
  Stop
  
  printf "%s\n" "  Waiting three seconds to prevent thrashing..."
  sleep 3
  
  Start
}

Configure(){
  local ServerName
  local Region
  local Bandwidth
  local MaxPlayers
  local RconPassword
  local SvPassword
  
  Title "Configure"
  EchoBold "  This configuration wizard will overwrite any existing server.cfg file."
  EchoGreen -n "  Would you like to continue? y/n: "; read LINE
  if [ "$LINE" = "y" ]; then
  
    printf "\n\n"
    EchoBold "  Server Name"
    Separator "="
    Longline "  This is the name of your server.  Give your server a creative name or one that people can find easily using the search function.  Using your screen name in the server name will help your friends find it easier, like \"Bob's Server\" or the like."
    Separator "-"
    EchoGreen -n "  Enter a name for this server: "; read ServerName

    printf "\n\n"
    EchoBold "  Region"
    Separator "="
    echo "  0 	US - East
  1 	US - West
  2 	South America
  3 	Europe
  4 	Asia
  5 	Australia
  6 	Middle East
  7 	Africa
  255 	World"
    Separator "-"
    EchoRed "  It is best to set the region for this server appropriately."
    Longline "  Default is 255 for World, i.e. no region.  This setting means that it will turn up regardless of what region people are searching under, however it will increase the likelyhood of getting clients that are geographically located farther away and thusly will have higher ping rates.  Best practice is to set the region to the region you belong to."
    EchoGreen -n "  Enter the region for this server: "; read Region
  
    InputBandwidth(){
      printf "\n\n"
      EchoBold "  Bandwidth"
      Separator "="
      EchoRed "  The amount of bandwidth you wish to dedicate to this server is critical."
      Longline "  This calculation will determine the amount of maximum players your server can handle.  If you specify more bandwidth than you have your server will lag.  Additionally it is important to actually reserve that bandwidth for the server by some means or another.  This is can be accomplished with your gateway.  DD-WRT has several features that can assist with this.  QoS can help, but it is best to actually throttle the other machines on your network so that the amount of bandwidth you have allocated is always available.  If you are simply running the server for you and your friends then usually you can manage bandwidth usage manually by turning off other services like torrent downloads before starting your server.  If other machines on your network eat into the bandwidth you have allocated for the server the server will lag.  Any lag will result in a higher ping and will rank your server lower on the server list with Steam.  You can check your bandwidth using speedtest.net or other bandwidth measuring tools if necessary.  Pay attention to the denotation involved, i.e. Mbps, KBps or kbps."
      Separator "-"
      EchoGreen "  Enter the amount of bandwidth you wish to"
      EchoGreen -n "  dedicate to this server in kilobits per second: "; read Bandwidth
  
      MaxPlayers=`expr $Bandwidth / 430000 - 1`
      if [ "$MaxPlayers" -gt 24 ]; then
        Longline "  This calculation has determined that your max players is $MaxPlayers.  Unless you have a massive internet connection this value may not be correct."
        EchoRed "  Would you like to retry this step? y/n: "; read LINE
        if [ "$LINE" = "y" ]; then InputBandwidth; fi
      fi
      echo "  We have determined your max players is $MaxPlayers."
    }; InputBandwidth

    printf "\n\n"
    EchoBold "  Remote Connection Password"
    Separator "="
    Longline "  This password is used for making remote console connections to this server.  You probably won't need this, but should set one anyway."
    Separator "-"
    EchoGreen -n "  Enter the rcon password: "; read RconPassword
    
    printf "\n\n"
    EchoBold "  Server Password"
    Separator "="
    Longline "  This password is used by clients to connect to the server.  If you do not want players to have to input a password to connect leave this blank."
    Separator "-"
    EchoGreen -n "  Enter the server password: "; read SvPassword
    
    printf "\n\n"
    EchoBold "  Writing Configuration File"
    Separator "="
    Longline "  We will now write the default configuration file for sandbox mode.  There are many tweaks that can be made to this file.  It is best to leave these values alone until you feel a need to change them.  The default configuration file is called \"server.cfg\" and is located at /home/steam/Steam/steamapps/common/GarrysModDS/garrysmod/cfg/server.cfg.  It might be easier to edit this file using the Samba share method from a computer with a text editor, or it can be edited from the command line with vi or the like.  If you have configured this server while it is running you will have to restart it for changes to take effect.  If you would like this configuration wizard to support another game mode besides sandbox you can email danielikard@gmail.com and I would be happy to assist."
    printf "\n"

    sudo su -c "echo \"hostname		\\\"$ServerName\\\"
rcon_password		\\\"$RconPassword\\\"
sv_password		\\\"$SvPassword\\\"
sv_region	 	$Region
sv_noclipspeed		5
sv_noclipaccelerate	5
sbox_allownpcs		0
sbox_godmode		0
sbox_plpldamage		0
sbox_playergod		0
sbox_noclip		1
sbox_maxprops		250
sbox_maxragdolls	5
sbox_maxnpcs		5
sbox_maxballons		25
sbox_maxeffects		25
sbox_maxdynamite	5
sbox_maxlamps		10
sbox_maxthrusters	250
sbox_maxwheels		50
sbox_maxhoverballs	50
sbox_maxvehicles	8
sbox_maxbuttons		50
sbox_maxsents		20
sbox_maxemitters	5
sbox_maxspawners	3
sbox_maxturrets		10

// Advanced options.  Created by ezgmodds.  You should probably leave these alone, but it's up to you...
sv_defaultgamemode	sandbox
maxplayers		$MaxPlayers
sv_lan			0
sv_logbans		1
sv_logecho		1
sv_logfile		1
sv_log_onefile		0
logging			on
net_maxfilesize		64
sv_minrate		0
sv_maxrate		424000
decalfrequency		10
sv_maxupdaterate	66
sv_minupdaterate	10
fps_max			600

exec banned_ip.cfg
exec banned_user.cfg
\" >/home/steam/Steam/steamapps/common/GarrysModDS/garrysmod/cfg/server.cfg" steam
  fi
}

Remove(){
    Title "Remove GarrysModDS"
    
    EchoRed "  This will remove GarrysModDS, including all data like addons and maps"
    EchoRed "  as well as the user \"steam\" and ALL DATA in the folder /home/steam"
    printf "%s" "    Are you sure? y/n: "; read LINE
    if [ "$LINE" = "y" ]; then
      Stop 1

      printf "%s" "  Removing Steam files"
      sudo rm -rf /home/steam 1>/dev/null 2>/dev/null
      Status

      if id -u steam >/dev/null 2>&1; then
        printf "%s" "  Removing user steam"
        sudo deluser steam 1>/dev/null 2>/dev/null
        Status
      fi

      printf "%s" "  Removing cron job"
      ( sudo crontab -l 2>/dev/null | grep -Fv ezgmodds_cron.sh ) | sudo crontab 1>/dev/null 2>/dev/null
      Status
    else
      EchoBold "  Remove GarrysModDS aborted."
    fi
    printf "\n"
}

Update(){
  if [ ! $1 ]; then
    Title "Checking for updates"
  fi
  
  printf "%s" "  Checking file limit"
  sudo su -c "ulimit -n 2048" steam
  Status

  sudo rm -f /tmp/ezgmodds.tmp
  printf "%s" "  Checking for updates for Steam"
  sudo su -c "bash /home/steam/steamcmd/steamcmd.sh +login anonymous +quit 1>/tmp/ezgmodds.tmp 2>&1" steam &
  PrintSteamCMDOut

  if [ -f /home/steam/Steam/steamapps/common/GarrysModDS/srcds_linux ]; then
    sudo rm -f /tmp/ezgmodds.tmp
    printf "%s" "  Checking for updates for GarrysModDS"
    sudo su -c "bash /home/steam/steamcmd/steamcmd.sh +login anonymous +app_update 4020 validate +quit 1>/tmp/ezgmodds.tmp 2>&1" steam &
    PrintSteamCMDOut
  fi

#  if [ "`uname -m`" != "i686" ]; then
#    printf "%s" "  Updating 32-bit libraries"
#    sudo mkdir -p /home/steam/.steam/sdk32
#    sudo cp -f /home/steam/steamcmd/linux32/* /home/steam/.steam/sdk32/
#    Status
#  fi
  
  if [ ! $1 ]; then
    printf "\n"
  fi
}

SambaOn(){

  if [ ! -f /usr/sbin/smbd ]; then
    Title "Start Samba"

    sudo rm -f /tmp/ezgmodds.tmp
    printf "%s" "  Updating repositories"
    sudo apt-get update 1>/tmp/ezgmodds.tmp 2>&1 &
    PrintAptGetOut

    sudo rm -f /tmp/ezgmodds.tmp
    printf "%s" "  Installing Samba"
    sudo apt-get -y install samba 1>/tmp/ezgmodds.tmp 2>&1 &
    PrintAptGetOut

    sudo stop smbd 1>/dev/null 2>/dev/null
    sudo stop nmbd 1>/dev/null 2>/dev/null
    sudo killall smbd 1>/dev/null 2>/dev/null
    sudo killall nmbd 1>/dev/null 2>/dev/null
    printf "  Enter the SMB user name: "; read SambaUserName
    sudo smbpasswd -a $SambaUserName
    sudo smbpasswd -e $SambaUserName
    printf "  Enter the SMB share name: "; read SambaName
    printf "  Enter the SMB share workgroup: "; read Workgroup
    sudo su -c "echo \"[global]
    netbios name = $SambaName
    server string = $SambaName
    workgroup = $Workgroup
    socket options = TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192
    passdb backend = tdbsam
    security = user
    username map = /etc/samba/smbusers
    name resolve order = hosts wins bcast
    wins support = yes
    syslog = 1
    syslog only = yes
    path = /home/steam/Steam

[Steam]
    browseable = yes
    read only = no
    guest ok = no
    create mask = 0644
    directory mask = 0755
    force user = steam
    force group = steam
\" >/etc/samba/smb.conf" root
    printf "\n"
  fi
  if top -bn 1 | grep "smbd" >/dev/null; then
    EchoRed "  Samba is already running"
  else
    printf "%s" "  Starting smbd"
    sudo start smbd 1>/dev/null 2>/dev/null
    Status

    printf "%s" "  Starting nmbd"
    sudo start nmbd 1>/dev/null 2>/dev/null
    Status
  fi

}

SambaOff(){
  Title "Stop Samba"

  printf "%s" "  Stopping smbd"
  sudo stop smbd 1>/dev/null 2>/dev/null
  Status

  printf "%s" "  Stopping nmbd"
  sudo stop nmbd 1>/dev/null 2>/dev/null
  Status
}

AutoStartOn(){
    Title "Autostart On"
    printf "%s" "  Adding ezgmodds_autostart cron job"
    ( sudo crontab -l 2>/dev/null | grep -Fv ezgmodds_autostart.sh; printf -- "@reboot /usr/etc/ezgmodds/ezgmodds_autostart.sh\n" ) | sudo crontab
    Status
}

AutoStartOff(){
    Title "Autostart Off"
    printf "%s" "  Removing ezgmodds_autostart cron job"
    ( sudo crontab -l 2>/dev/null | grep -Fv ezgmodds_autostart.sh; printf -- "\n" ) | sudo crontab
    Status
}

Usage(){
  Title "ezgmodds"
  Longline "    `EchoBold ex: \'ezgmodds install 4020\' or \'ezgmodds autostart on\'`\n"
  Longline "  `EchoBold install`: Installs GarrysModDS including SteamCMD and the user \"steam\", if necessary and then runs the configuration wizard."
  Longline "  `EchoBold update`: Updates GarrysModDS and SteamCMD."
  Longline "  `EchoBold remove`: Removes GarrysModDS and SteamCMD, including the user \"steam\", /home/steam and it's contents."
  Longline "  `EchoBold start`: Starts the server."
  Longline "  `EchoBold stop`: Stops the server."
  Longline "  `EchoBold \"restart\"`: Restarts the server."
  Longline "  `EchoBold \"configure\"`: Runs the configuration wizard."
  Longline "  `EchoBold \"console\"`: Enters the GarrysModDS console."
  Longline "  `EchoBold \"samba [on|off]\"`: Starts or stops the Samba share of /home/steam/Steam."
  Longline "  `EchoBold \"autostart [on|off]\"`: Enables or disables autostart of GarrysModDS on machine startup."
  Separator "-"
  if [ ! -f /home/steam/Steam/steamapps/common/GarrysModDS/srcds_linux ]; then
    EchoRed "  GarrysModDS is not installed"
  else
    if top -bn 1 | grep "srcds_linux" >/dev/null; then
      EchoGreen "  GarrysModDS is running"
    else
      EchoRed "  GarrysModDS is not running"
    fi  
  fi
  printf "\n"
}

Cron(){
  echo "  ezgmodds cron triggered - `date +"%T"`" >/tmp/ezgmodds_cronrecord
}

Console(){
  Screen(){
    echo "  Now entering the Garry's Mod console."
    EchoBold "  Press ctrl-a-d to return to the command line."
    echo "  Press enter to continue..."; read LINE
    clear
    sudo su -c "/usr/bin/script -q -c \"/usr/bin/screen -x GarrysModDS\" /dev/null" steam
  }
  Title "GarrysModDS Console"
  if top -bn 1 | grep "srcds_linux" >/dev/null; then
    Screen
  else
    EchoRed "  GarrysModDS is not running."
    echo -n "  Would you like to start the server? y/n: "; read LINE
    if [ "$LINE" = "y" ]; then
      Start 1
      Screen
    fi
  fi
  printf "\n"
}





if [ ! $1 ]; then
  Usage
  exit 0
else
  LINE="$1"
fi
if [ "$LINE" = "remove" ]; then Remove
elif [ "$LINE" = "update" ]; then Update
elif [ "$LINE" = "install" ]; then Install
elif [ "$LINE" = "start" ]; then Start
elif [ "$LINE" = "stop" ]; then Stop
elif [ "$LINE" = "restart" ]; then Restart
elif [ "$LINE" = "console" ]; then Console
elif [ "$LINE" = "configure" ]; then Configure
elif [ "$LINE" = "cron" ]; then Cron
elif [ "$LINE" = "samba" ]; then
  if [ $2 = "on" ]; then SambaOn
  elif [ $2 = "off" ]; then SambaOff
  fi
elif [ "$LINE" = "autostart" ]; then
  if [ $2 = "on" ]; then AutoStartOn
  elif [ $2 = "off" ]; then AutoStartOff
  fi
elif [ "$LINE" = "-help"]; then Usage
elif [ "$LINE" = "--help"]; then Usage
elif [ "$LINE" = "-h"]; then Usage
fi
exit 0
